package com.github.bobjoy.java.math;

import java.math.BigDecimal;

/**
 * 1.不推荐使用BigDecimal(double val)构造器，因为使用该构造器时有一定的不可预知性，当程序使用new BigDecimal(0.1)创建一个BigDecimal对象时，它的值并不是0.1，实际上是一个近似0.1的数。
 * 2.建议优先使用基于String的构造器，使用BigDecimal(String val)构造器时可以预知的，写入new BigDecimal("0.1")将创建一个恰好等于0.1的BigDecimal。
 * 3.如果必须使用double浮点数作为BigDecimal构造器的参数时，不要使用double作为参数，而应该通过BigDecimal.valueOf(double value)静态方法来创建对象。
 */
public class BigDecimalDemo {

    public static void main(String[] args) {
        double d1 = 0.45, d2 = 0.63;

        System.out.println("double构造");
        System.out.println(new BigDecimal(d1));
        System.out.println(new BigDecimal(d2));
        System.out.println("-------------------------------");

        System.out.println("string构造");
        System.out.println(new BigDecimal(Double.toString(d1)));
        System.out.println(new BigDecimal(Double.toString(d2)));
        System.out.println("-------------------------------");

        System.out.println("加法");
        System.out.println(d1 + d2);
        System.out.println(BigDecimalHelper.add(d1, d2));
        System.out.println("-------------------------------");

        System.out.println("减法");
        System.out.println(d1 - d2);
        System.out.println(BigDecimalHelper.sub(d1, d2));
        System.out.println("-------------------------------");

        System.out.println("乘法");
        System.out.println(d1 * d2);
        System.out.println(BigDecimalHelper.mul(d1, d2));
        System.out.println("-------------------------------");

        System.out.println("除法");
        System.out.println(d1 / d2);
        System.out.println(BigDecimalHelper.div(d1, d2, 2));


    }

}

class BigDecimalHelper {

    private final static int DEFAULT_DIV_SCALA = 10;

    private BigDecimalHelper() {}

    public static double add(double d1, double d2) {
        BigDecimal bd1 = BigDecimal.valueOf(d1);
        BigDecimal bd2 = BigDecimal.valueOf(d2);
        return bd1.add(bd2).doubleValue();
    }

    public static double sub(double d1, double d2) {
        BigDecimal bd1 = BigDecimal.valueOf(d1);
        BigDecimal bd2 = BigDecimal.valueOf(d2);
        return bd1.subtract(bd2).doubleValue();
    }

    public static double mul(double d1, double d2) {
        BigDecimal bd1 = BigDecimal.valueOf(d1);
        BigDecimal bd2 = BigDecimal.valueOf(d2);
        return bd1.multiply(bd2).doubleValue();
    }

    public static double div(double d1, double d2) {
        return div(d1, d2, DEFAULT_DIV_SCALA);
    }

    public static double div(double d1, double d2, int scala) {
        BigDecimal bd1 = BigDecimal.valueOf(d1);
        BigDecimal bd2 = BigDecimal.valueOf(d2);
        return bd1.divide(bd2, scala, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static double round(double d, int scala) {
        return div(d, 1, scala);
    }
}
